package tcp_proxy_middleware

import (
	"context"
	"math"
	"net"

	"go_gateway/tcp_server"
)

/*
1. NewTcpSliceRouter()       创建路由器
2. Group("/").Use(...)       注册中间件
3. NewTcpSliceRouterHandler()创建处理器
4. ServeTCP()                连接入口
   ↓
5. newTcpSliceRouterContext()创建上下文
   ↓
6. Reset()                   重置索引
   ↓
7. Next()                    开始执行中间件链
   ↓
8. 中间件1 → 中间件2 → ... → 核心处理器
   (每个中间件可调用 Next() 或 Abort())
*/

const abortIndex int8 = math.MaxInt8 / 2 //最多 63 个中间件

// 知其然也知其所以然
type TcpHandlerFunc func(*TcpSliceRouterContext)

// 路由器router 结构体
type TcpSliceRouter struct {
	groups []*TcpSliceGroup // 路由分组列表
}

// 路由分组group 结构体
type TcpSliceGroup struct {
	*TcpSliceRouter                  // 嵌入路由器
	path            string           // 路径（TCP中固定为"/"）
	handlers        []TcpHandlerFunc // 中间件函数列表
}

// router上下文
type TcpSliceRouterContext struct {
	conn           net.Conn        // TCP连接
	Ctx            context.Context // 上下文
	*TcpSliceGroup                 // 当前分组
	index          int8            // 当前执行的中间件索引
}

// 创建上下文：为每个 TCP 连接创建执行上下文
func newTcpSliceRouterContext(conn net.Conn, r *TcpSliceRouter, ctx context.Context) *TcpSliceRouterContext {
	newTcpSliceGroup := &TcpSliceGroup{}
	*newTcpSliceGroup = *r.groups[0] //浅拷贝数组指针,只会使用第一个分组
	c := &TcpSliceRouterContext{conn: conn, TcpSliceGroup: newTcpSliceGroup, Ctx: ctx}
	c.Reset()
	return c
}

// 从上下文获取值
func (c *TcpSliceRouterContext) Get(key interface{}) interface{} {
	return c.Ctx.Value(key)
}

// 向上下文设置值
func (c *TcpSliceRouterContext) Set(key, val interface{}) {
	c.Ctx = context.WithValue(c.Ctx, key, val)
}

// 路由处理器
type TcpSliceRouterHandler struct {
	coreFunc func(*TcpSliceRouterContext) tcp_server.TCPHandler
	router   *TcpSliceRouter
}

// 路由处理器入口：TCP 连接的处理入口点
func (w *TcpSliceRouterHandler) ServeTCP(ctx context.Context, conn net.Conn) {
	// 创建执行上下文
	c := newTcpSliceRouterContext(conn, w.router, ctx)
	// 将核心处理器包装成中间件添加到链尾
	c.handlers = append(c.handlers, func(c *TcpSliceRouterContext) {
		w.coreFunc(c).ServeTCP(ctx, conn)
	})
	// 重置执行索引
	c.Reset()
	// 开始执行中间件链
	c.Next()
}

// 创建路由处理器
func NewTcpSliceRouterHandler(coreFunc func(*TcpSliceRouterContext) tcp_server.TCPHandler, router *TcpSliceRouter) *TcpSliceRouterHandler {
	return &TcpSliceRouterHandler{
		coreFunc: coreFunc,
		router:   router,
	}
}

// 创建路由器
func NewTcpSliceRouter() *TcpSliceRouter {
	return &TcpSliceRouter{}
}

// 创建路由分组
func (g *TcpSliceRouter) Group(path string) *TcpSliceGroup {
	if path != "/" {
		panic("only accept path=/")
	}
	return &TcpSliceGroup{
		TcpSliceRouter: g,
		path:           path,
	}
}

// 注册中间件：向路由分组添加中间件
func (g *TcpSliceGroup) Use(middlewares ...TcpHandlerFunc) *TcpSliceGroup {
	g.handlers = append(g.handlers, middlewares...)
	existsFlag := false
	for _, oldGroup := range g.TcpSliceRouter.groups {
		if oldGroup == g {
			existsFlag = true
		}
	}
	if !existsFlag {
		g.TcpSliceRouter.groups = append(g.TcpSliceRouter.groups, g)
	}
	return g
}

// 执行下一个中间件
func (c *TcpSliceRouterContext) Next() {
	c.index++
	for c.index < int8(len(c.handlers)) {
		c.handlers[c.index](c) // 执行中间件
		c.index++
	}
}

// 终止机制
func (c *TcpSliceRouterContext) Abort() {
	c.index = abortIndex // 设置索引为终止值
}

// 检查是否已终止
func (c *TcpSliceRouterContext) IsAborted() bool {
	return c.index >= abortIndex
}

// 重置执行状态
func (c *TcpSliceRouterContext) Reset() {
	c.index = -1
}
